"""
脚本运行管理器
"""
import sys
from pathlib import Path
sys.path.append(str(Path(__file__).parent.parent))

from typing import Dict, List
from com.db.script_manager import ScriptManager
from biz.script_task_processor import ScriptTaskProcessor
import threading
import time
from PyQt6.QtCore import QObject, pyqtSignal
from com.utils.logger import get_logger,MODULE_SCAN

class ScriptRunner(QObject):
    """脚本运行管理器，负责管理所有运行中的脚本任务"""
    
    # 日志信号
    log_signal = pyqtSignal(str)
    
    def __init__(self):
        super().__init__()
        self.script_manager = ScriptManager()
        self.running_processors: Dict[int, ScriptTaskProcessor] = {}  # script_id -> processor
        self._lock = threading.Lock()
        self.logger = get_logger(module=MODULE_SCAN)
        
    def log(self, message: str):
        """发送日志消息"""
        try:
            self.log_signal.emit(message)
            self.logger.info(message)
        except:
            self.logger.info(message)
        
    def start_script(self, script_id: int, interval: int = 1) -> bool:
        """
        启动一个脚本
        
        Args:
            script_id: 脚本ID
            interval: 任务处理间隔（秒）
            
        Returns:
            bool: 是否成功启动
        """
        with self._lock:
            # 检查脚本是否已经在运行
            if script_id in self.running_processors:
                self.log(f"脚本 {script_id} 已经在运行中")
                # 确保数据库状态与实际运行状态一致
                self.script_manager.update_run_status(script_id, 1)  # 1表示运行中
                return True
                
            # 检查脚本是否存在且有效
            script = self.script_manager.get_script_by_id(script_id)
            if not script:
                self.log(f"脚本 {script_id} 不存在")
                return False
                
            if script['status'] != 1:
                self.log(f"脚本 {script_id} 未启用")
                return False
                
            # 创建并启动处理器
            processor = ScriptTaskProcessor()
            processor.start(script_id, interval)
            
            # 记录运行中的处理器
            self.running_processors[script_id] = processor
            
            # 更新数据库中脚本的运行状态
            self.script_manager.update_run_status(script_id, 1)  # 1表示运行中
            
            self.log(f"脚本 {script_id} ({script['name']}) 已启动")
            return True
            
    def stop_script(self, script_id: int) -> bool:
        """
        停止一个脚本
        
        Args:
            script_id: 脚本ID
            
        Returns:
            bool: 是否成功停止
        """
        with self._lock:
            processor = self.running_processors.get(script_id)
            if not processor:
                self.log(f"脚本 {script_id} 未在运行")
                return False
                
            processor.stop()
            del self.running_processors[script_id]
            
            # 更新数据库中脚本的运行状态
            self.script_manager.update_run_status(script_id, 0)  # 0表示停止
            
            self.log(f"脚本 {script_id} 已停止")
            return True
            
    def stop_all(self):
        """停止所有运行中的脚本"""
        with self._lock:
            for script_id, processor in list(self.running_processors.items()):
                processor.stop()
                # 更新数据库中脚本的运行状态
                self.script_manager.update_run_status(script_id, 0)  # 0表示停止
                self.log(f"脚本 {script_id} 已停止")
            self.running_processors.clear()
            
    def start_active_scripts(self):
        """启动所有启用的脚本"""
        active_scripts = self.script_manager.get_active_scripts()
        if not active_scripts:
            self.log("没有找到启用的脚本")
            return
            
        self.log(f"找到 {len(active_scripts)} 个启用的脚本")
        for script in active_scripts:
            script_id = script['id']
            self.start_script(script_id)
            
    def get_running_scripts(self) -> List[int]:
        """获取所有运行中的脚本ID"""
        with self._lock:
            return list(self.running_processors.keys())
            
    def is_running(self) -> bool:
        """检查是否有脚本在运行
        
        Returns:
            bool: 是否有脚本在运行
        """
        with self._lock:
            return len(self.running_processors) > 0
            
# 全局单例
_instance = None
_instance_lock = threading.Lock()

def get_script_runner() -> ScriptRunner:
    """获取 ScriptRunner 单例"""
    global _instance
    if _instance is None:
        with _instance_lock:
            if _instance is None:
                _instance = ScriptRunner()
    return _instance
